package site.lanmushan.framework.mapper.provider;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import site.lanmushan.framework.mapper.annotation.SlashLogicDelete;
import site.lanmushan.framework.mapper.util.SlashSqlHelper;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
import tk.mybatis.mapper.util.MetaObjectUtil;

import java.util.Set;

/**
 * @author Administrator
 */
public class DeleteWrapperMapperProvider extends MapperTemplate {
    public DeleteWrapperMapperProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }


    /**
     * 逻辑删除
     *
     * @param ms
     * @return
     */
    public String logicDeleteByPrimaryKey(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        // 如果是逻辑删除，则修改为更新表，修改逻辑删除字段的值
        if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
            sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
            sql.append("<set>");
            sql.append(logicDeleteColumnEqualsValue(entityClass, true));
            sql.append("</set>");
            MetaObjectUtil.forObject(ms).setValue("sqlCommandType", SqlCommandType.UPDATE);
        } else {
            sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
        }
        sql.append(SqlHelper.wherePKColumns(entityClass));
        return sql.toString();
    }

    public String logicDeleteQueryWrapper(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        // 如果是逻辑删除，则修改为更新表，修改逻辑删除字段的值
        if (getLogicDeleteColumn(entityClass)!=null) {
            MetaObjectUtil.forObject(ms).setValue("sqlCommandType", SqlCommandType.UPDATE);
            sql.append("update");
            sql.append(SlashSqlHelper.createSqlTableName(EntityHelper.getEntityTable(entityClass).getName()));
            sql.append("<set>");
            sql.append(logicDeleteColumnEqualsValue(entityClass, true));
            sql.append("</set>");
            sql.append("<where>");
            String deletedColumn = getLogicDeleteColumnName(entityClass);
            if (deletedColumn != null) {
                sql.append(deletedColumn + " = 0");
            }
            sql.append("${@site.lanmushan.framework.mapper.util.QueryWrapperUtil@createWhereString(query)}");
            sql.append("</where>");
        } else {
            sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
            sql.append("<where>");
            String deletedColumn = getLogicDeleteColumnName(entityClass);
            if (deletedColumn != null) {
                sql.append(deletedColumn + " = 0");
            }
            sql.append("${@site.lanmushan.framework.mapper.util.QueryWrapperUtil@createWhereStringNull(query)}");
            sql.append("</where>");
        }

        return sql.toString();
    }

    public static String logicDeleteColumnEqualsValue(Class<?> entityClass, boolean isDeleted) {
        EntityColumn logicDeleteColumn = getLogicDeleteColumn(entityClass);
        if (logicDeleteColumn != null) {
            return logicDeleteColumnEqualsValue(logicDeleteColumn);
        }

        return "";
    }

    public static String logicDeleteColumnEqualsValue(EntityColumn column) {
        String result = "";
        if (column.getEntityField().isAnnotationPresent(SlashLogicDelete.class)) {
            result = "tb."+column.getColumn() + " = " + System.currentTimeMillis();
        }
        return result;
    }
    public static EntityColumn getLogicDeleteColumn(Class entityClass)
    {
        Set<EntityColumn> entityColumnSet = EntityHelper.getColumns(entityClass);
        for (EntityColumn column: entityColumnSet ) {
            if (column.getEntityField().isAnnotationPresent(SlashLogicDelete.class)) {
              return column;
            }
        }
        return null;
    }
    public static String getLogicDeleteColumnName(Class entityClass) {
        EntityColumn logicDeleteColumn = SqlHelper.getLogicDeleteColumn(entityClass);
        if(logicDeleteColumn==null)
        {
            return null;
        }
        if (logicDeleteColumn.getEntityField().isAnnotationPresent(SlashLogicDelete.class)) {
            SlashLogicDelete slashLogicDelete = logicDeleteColumn.getEntityField().getAnnotation(SlashLogicDelete.class);
            return logicDeleteColumn.getColumn();
        }
        return null;
    }
}
